Sala situacional Salud intercultural e Investigación Social (2019-2024)
  • Inicio
  • Hepatitis B
  • Tuberculosis
  • Desnutricion
  • VIH

On this page

  • VIH por etnicidad
  • VIH en los 55 pueblos indígenas u originarios
  • Clasificación en el diagnóstico de VIH en poblaciones afroperuanas, andinas y amazónicas 2019-2023
  • VIH en poblaciones amazónicas, andinas y población afroperuana por sexo 2019-2023
  • VIH en poblaciones amazónicas, andinas y afroperuana por curso de vida 2019-2023
  • Distribución de la infección por VIH por departamentos 2019-2025

VIH en las poblaciones amazónicas, andinas y afroperuanas

Análisis de datos del Ministerio de Salud (MINSA)

Author

Subdirección de Medicina Tradicional, Interculturalidad e Investigación Social (SUMEC-CENSI)

Published

December 19, 2025

El sida es la otra pandemia que afecta a la población mundial y aunque las personas con VIH reciben tratamiento y unido a la calidad de vida se detiene el avance de la enfermedad, sin embargo, sigue cobrando la vida de miles de personas.

El 15 de junio del 2021 se cumplieron 40 años de la primera descripción clínica de los casos a lo que más adelante tomo el nombre del Síndrome de Inmunodeficiencia Adquirida (SIDA).

Según información del Ministerio de Salud en nuestro país, el 2022, hay aproximadamente 70 000 personas afectadas con VIH.

A continuación, se presenta información desagregada por poblaciones indígenas amazónicas y andinas y la población afroperuana desde el 2019 hasta el 2023. Esta información proviene de la data del HIS Ministerio de Salud.

Según el CIE 10, Clasificación Estadística Internacional de Enfermedades y Problemas Relacionados con la Salud, elaborado por la Organización Mundial de la Salud, se considera estas categorías en el VIH:

  • Enfermedad por Virus de la Inmunodeficiencia Humana [VIH], resultante en enfermedades ­infecciosas y parasitarias.

  • Enfermedad por Virus de la Inmunodeficiencia Humana [VIH], resultante en tumores malignos.

  • Enfermedad por Virus de la Inmunodeficiencia Humana [VIH], resultante en otras enfermedades especificadas.

  • Enfermedad por Virus de la Inmunodeficiencia Humana [VIH], resultante en otras afecciones.

  • Enfermedad por Virus de la Inmunodeficiencia Humana [VIH], sin otra especificación.

VIH por etnicidad

Los mayores registros de VIH se dieron en los mestizos. Seguido por los amazónicos, andinos y la población afroperuana. Se observa la disminución en los registros de VIH el 2020 hasta el 2021, esto es por la disminución de la detección de casos por la pandemia del COVID-19.

  • Gráfico
  • Datos Fuente
Code
#| echo: false
#| warning: false
#| message: false

library(tidyverse)
library(plotly)
library(scales)
library(DT)

# --- FUNCIÓN AUXILIAR PARA TABLAS DE DESCARGA ---
# Esta función crea estandariza el botón de Excel para todos los gráficos
make_download_table <- function(data_input, filename_label = "datos") {
  datatable(
    data_input,
    extensions = 'Buttons',
    rownames = FALSE,
    options = list(
      dom = 'Bfrtip',
      buttons = list(
        list(extend = 'excel', filename = filename_label, title = filename_label),
        list(extend = 'csv', filename = filename_label)
      ),
      pageLength = 5, # Pocas filas para no ocupar mucho espacio
      scrollX = TRUE,
      language = list(url = '//cdn.datatables.net/plug-ins/1.10.11/i18n/Spanish.json')
    )
  )
}

# 1. DATOS TRANSCRITOS (Imagen Excel)
# Nota: Los guiones "-" los he interpretado como 0 para mantener la continuidad de la línea.
data_tendencia_etnias <- tribble(
  ~Año, ~Afroperuano, ~Andinos, ~Amazónicos, ~Mestizo,
  2019, 0, 31, 390, 26174,
  2020, 4, 25, 352, 15060,
  2021, 0, 34, 627, 19045,
  2022, 3, 49, 719, 25727,
  2023, 0, 66, 848, 29802,
  2024, 2, 49, 727, 29968,
  2025, 0, 53, 555, 20141
)

# 2. PROCESAMIENTO
plot_data_final <- data_tendencia_etnias %>%
  pivot_longer(
    cols = c("Afroperuano", "Andinos", "Amazónicos", "Mestizo"), 
    names_to = "Etnia", 
    values_to = "Casos"
  ) %>%
  mutate(
    # Tooltip personalizado para ver los datos claros al pasar el mouse
    Tooltip_Text = paste0(
      "<b>", Etnia, "</b><br>",
      "Año: ", Año, "<br>",
      "Casos: ", format(Casos, big.mark = ",")
    )
  )

# 3. GRÁFICO DE LÍNEAS CON ESCALAS LIBRES
g_tendencias_final <- ggplot(plot_data_final, aes(x = Año, y = Casos, color = Etnia)) +
  
  # Líneas y Puntos
  geom_line(linewidth = 1.1) +
  geom_point(aes(text = Tooltip_Text), size = 2.5) +
  
  # --- CLAVE DEL ÉXITO VISUAL ---
  # scales = "free_y": Permite que Mestizos llegue a 30k y Afroperuanos a 4
  # sin que ninguno se vea aplastado.
  facet_wrap(~Etnia, scales = "free_y", ncol = 2) +
  
  # Colores diferenciados
  scale_color_brewer(palette = "Set1") +
  
  # Ajustes de Ejes
  scale_x_continuous(breaks = 2019:2025) + # Forzamos que salgan todos los años
  scale_y_continuous(labels = scales::comma, limits = c(0, NA)) + # Comas para miles y base 0
  
  labs(
    title = "Tendencia de casos por etnia (2019-2025)",
    subtitle = "Escalas independientes por grupo para visualizar evolución",
    x = "",
    y = "Número de Casos"
  ) +
  
  theme_minimal() +
  theme(
    plot.title = element_text(face = "bold", size = 14),
    strip.text = element_text(face = "bold", size = 11),
    strip.background = element_rect(fill = "#f5f5f5", color = NA),
    legend.position = "none", # No hace falta leyenda, el título de cada cuadro lo dice
    panel.grid.minor = element_blank()
  )

# 4. INTERACTIVIDAD
ggplotly(g_tendencias_final, tooltip = "text") %>%
  layout(
    margin = list(t = 60),
    autosize = TRUE
  )
Code
make_download_table(data_tendencia_etnias, "data_tendencia_etnias")
  • Grafico
  • Datos Fuente
Code
#| echo: false
#| warning: false
#| message: false
#| fig-height: 900 

library(tidyverse)
library(plotly)
library(viridis)

# 1. DATOS (Los mismos de la imagen panorámica)
data_etnias_full <- tribble(
  ~Etnia, ~`2019`, ~`2020`, ~`2021`, ~`2022`, ~`2023`, ~`2024`, ~`2025`,
  "Achuar", 7, 5, 6, 11, 11, 30, 14,
  "Afroperuano", 0, 4, 0, 3, 0, 2, 0,
  "Aimara", 10, 10, 7, 6, 8, 4, 5,
  "Amahuaca", 5, 13, 1, 7, 2, 1, 3,
  "Arabela", 1, 8, 2, 1, 1, 0, 1,
  "Ashaninka", 9, 10, 39, 83, 36, 76, 31,
  "Asheninka", 0, 2, 7, 15, 14, 16, 8,
  "Awajún", 262, 219, 434, 434, 155, 424, 281,
  "Bora", 3, 2, 2, 2, 1, 1, 6,
  "Capanahua", 0, 1, 1, 0, 0, 0, 0,
  "Cashinahua", 1, 2, 0, 7, 3, 0, 1,
  "Chapra", 0, 1, 0, 0, 0, 1, 3,
  "Chitonahua", 0, 0, 0, 0, 0, 3, 4,
  "Ese Eja", 0, 1, 0, 5, 2, 0, 0,
  "Harakbut", 0, 1, 0, 1, 2, 0, 0,
  "Iñapari", 0, 0, 0, 0, 0, 1, 2,
  "Jaqaru", 1, 0, 0, 0, 0, 4, 2,
  "Jíbaro", 0, 0, 0, 0, 0, 3, 1,
  "Kakinte", 0, 0, 0, 0, 0, 0, 2,
  "Kakataibo", 0, 5, 0, 0, 0, 1, 0,
  "Kandozi", 2, 0, 3, 4, 1, 10, 5,
  "Kichwa", 2, 19, 3, 9, 1, 60, 74,
  "Kukama Kukamiria", 23, 1, 16, 20, 8, 12, 6,
  "Madija", 6, 0, 8, 14, 2, 0, 1,
  "Maijuna", 2, 0, 0, 0, 1, 0, 2,
  "Matsés", 0, 0, 0, 0, 0, 1, 1,
  "Matsigenka", 0, 0, 0, 2, 0, 0, 0,
  "Murui-Muinani", 0, 2, 0, 4, 0, 2, 0,
  "Nahua", 1, 1, 0, 1, 2, 0, 0,
  "Nanti", 0, 0, 0, 0, 2, 0, 1,
  "Nomatsigenga", 0, 0, 6, 0, 0, 0, 1,
  "Quechuas", 15, 1, 1, 2, 0, 0, 1,
  "Sharanahua", 26, 15, 0, 43, 23, 41, 46,
  "Shawi", 0, 1, 0, 3, 0, 5, 1,
  "Shipibo-Konibo", 6, 7, 27, 9, 2, 21, 24,
  "Shiwilu", 0, 14, 3, 33, 20, 19, 25,
  "Tikuna", 16, 0, 7, 1, 0, 4, 0,
  "Urarina", 0, 0, 8, 0, 1, 1, 3,
  "Wampis", 1, 0, 0, 0, 1, 1, 2,
  "Yagua", 2, 1, 2, 36, 5, 25, 26,
  "Yaminahua", 0, 2, 1, 5, 0, 1, 2,
  "Yanesha", 0, 2, 74, 3, 0, 1, 0,
  "Yine", 0, 0, 0, 1, 1, 6, 4
)

# 2. PROCESAMIENTO
# Necesitamos formato largo para el Heatmap
plot_data_heatmap <- data_etnias_full %>%
  pivot_longer(cols = `2019`:`2025`, names_to = "Año_Texto", values_to = "Casos") %>%
  mutate(
    Año = as.numeric(Año_Texto),
    # Calculamos el total por etnia para ordenar el gráfico (Las que tienen más casos, arriba)
    Total_Por_Etnia = ave(Casos, Etnia, FUN = sum), 
    # --- EL TRUCO PARA EL COLOR ---
    # Creamos una columna específica para pintar.
    # Si Casos es 0, ponemos NA (para que no se pinte).
    # Si es > 0, mantenemos el número.
    Casos_Fill = ifelse(Casos == 0, NA, Casos),
    
    # Tooltip: Usamos la columna original 'Casos' para que muestre "0" y no "NA"
    Tooltip_Text = paste0("<b>", Etnia, "</b><br>",
                          "Año: ", Año, "<br>",
                          "Casos: ", Casos)
  )
# 3. GRÁFICO HEATMAP
g_heatmap <- ggplot(plot_data_heatmap, aes(x = factor(Año), y = reorder(Etnia, Total_Por_Etnia))) +
  
  # Usamos Casos_Fill para el relleno (color), pero Tooltip_Text para el mouse
  geom_tile(aes(fill = Casos_Fill, text = Tooltip_Text), color = "white", size = 0.2) +
  
  # ESCALA DE COLORES
  # na.value = "#f5f5f5": Esto pinta los NA (nuestros ceros) de un gris muy suave
  scale_fill_viridis_c(
    option = "magma", 
    direction = -1, 
    name = "Casos",
    na.value = "#f5f5f5" 
  ) +
  
  scale_x_discrete(position = "top") + 
  
  labs(
    title = "Mapa de Calor: Intensidad de casos por Etnia y Año",
    subtitle = "El color aparece solo si hay al menos 1 caso registrado",
    x = "",
    y = ""
  ) +
  
  theme_minimal() +
  theme(
    plot.title = element_text(face = "bold", size = 14, margin = margin(b=5)),
    plot.subtitle = element_text(size = 10, color = "gray40", margin = margin(b=10)),
    axis.text.x = element_text(face = "bold"),
    axis.text.y = element_text(size = 9),
    panel.grid = element_blank(), 
    legend.position = "right"
  )
# 4. INTERACTIVIDAD
# Nota: Plotly por defecto hace los NA transparentes, lo cual funciona perfecto aquí.
ggplotly(g_heatmap, tooltip = "text", height = 900) %>%
  layout(
    margin = list(l = 150, t = 100), 
    xaxis = list(side = "top") 
  )
Code
make_download_table(data_etnias_full, "data_etnias_full")

En comparación con las poblaciones afroperuana y andinas, en las poblaciones amazónicas se registran más casos de VIH y aunque el 2020 hubo una leve disminución de los registros en 10%, en comparación al 2019; el 2021, aun con la coyuntura de la pandemia por la Covid-19, tuvo un significativo incremento con respecto al año anterior en 78%.

En la población andina y, especialmente, en la población afroperuana, se observa un bajo registro en la detección de casos. El 2023, en la población afroperuana, no se registró ninguna atención. Aún esta pendiente determinar los factores que limitan el uso de la variable étnica.

VIH en los 55 pueblos indígenas u originarios

En el periodo analizado, las etnias que aparecen en los primeros lugares con más casos registrados son los Awajún, Kiwcha, Wampis, Shipibo-Konibo.

  • Tabla dinámica
  • Datos fuentes

Tabla 1 VIH en pueblos originarios 2019-2025

Code
make_download_table(data_vih_final, "data_vih_pueblos_originarios")

El 62% de los casos de VIH del total de casos en las poblaciones andinas amazónicas y afroperuanas, durante el 2019, corresponden a la etnia awajún. El 2020, 2021 y 2022, el 65%, 77% y 67% de los casos de VIH fueron de las etnias awajún y wampis. El 2023, los awajún y ashaninkas representan el 62%. Del 2021 al 2022, los ashaninkas aumentaron en 80% los registros con diagnóstico de VIH. Otra de las etnias que se observa aumento son los Wampis, del 2019 al 2020 aumentó del 94% y del 2020 al 2021, 139%.

  • Grafico
  • Datos fuentes
Code
make_download_table(data_vih_long, "data_raw")

Clasificación en el diagnóstico de VIH en poblaciones afroperuanas, andinas y amazónicas 2019-2023

  • Tabla dinámica
  • Datos fuentes

La categoría con más registros fue Enfermedad por VIH, sin otra especificación.

Tabla 2: Clasificación de diagnósticos de VIH por Etnia

Haga clic en el nombre del grupo étnico (flecha) para ver el detalle.

Code
make_download_table(data_tabla2, "data_clasificacion_diagnosticos_VIH")

VIH en poblaciones amazónicas, andinas y población afroperuana por sexo 2019-2023

  • Grafico
  • Datos fuentes
Code
make_download_table(data_grafico3, "data_VIH_por_sexo_y_etnia")

VIH en poblaciones amazónicas, andinas y afroperuana por curso de vida 2019-2023

  • Gráfico
  • Datos fuentes

Tanto en andinos como en afroperuanos, las edades con mayores registros de casos son los adultos de 30 a 59 años. En las poblaciones amazónicas son los jóvenes de 18 a 29 años con más del 50% de las atenciones. En las poblaciones andinas se observa un incremento en este mismo grupo de edad, en relación al 2022, el 2023 aumentó en más del 100% sus atenciones.

Code
make_download_table(data_raw, "data_vih_por_curso_de_vida")

Distribución de la infección por VIH por departamentos 2019-2025

  • Mapa: VIH en población afroperuana por departamentos 2019-2025.
  • Datos fuentes

Según los casos registrados por departamento, el 2020 dos (02) corresponden a Loreto y dos (02) a Piura. El 2022 registraron Ica (02) y Lambayeque (1). No hubo registros de casos el 2019, 2021 y el 2023.

Code
make_download_table(data_raw, "data_vih_afroperuana_por_departamento")
  • Mapa: VIH en Poblaciones Amazónicas (2019-2025).
  • Datos fuentes
Code
make_download_table(data_amazonicos_raw, "data_vih_poblacion_amazonica")
  • Mapa: VIH en Poblaciones Andinas (2019-2025).
  • Datos fuentes
Code
#| echo: false
#| warning: false
#| message: false
#| fig-height: 7

library(tidyverse)
library(plotly)
library(sf)
library(jsonlite)

# 1. CARGA DE MAPA (GEOJSON)
# Reutilizamos el mismo archivo local
archivo_geojson <- "peru_departamental_simple.geojson"

tryCatch({
  mapa_sf <- st_read(archivo_geojson, quiet = TRUE)
  geojson_peru <- jsonlite::fromJSON(archivo_geojson, simplifyVector = FALSE)
}, error = function(e) {
  stop("Error: No se encuentra el archivo 'peru_departamental_simple.geojson'.")
})

# 2. DATOS RECONSTRUIDOS (Población Andina - Extraídos de Flourish)
# Nota: He normalizado nombres como "Apurïmac" -> "APURIMAC" y "Lima 1/" -> "LIMA"
data_andinos_raw <- tribble(
  ~Departamento, ~`2019`, ~`2020`, ~`2021`, ~`2022`, ~`2023`, ~`2024`, ~`2025`,
  "AMAZONAS", 0, 0, 0, 0, 0, 0, 0,
  "ANCASH", 0, 2, 4, 7, 1, 3, 6,
  "APURIMAC", 0, 0, 0, 0, 0, 2, 0,
  "AREQUIPA", 0, 3, 0, 0, 0, 0, 2,
  "AYACUCHO", 13, 5, 18, 17, 29, 5, 2,
  "CAJAMARCA", 0, 0, 0, 0, 0, 0, 0,
  "CALLAO", 1, 1, 0, 0, 0, 0, 0,
  "CUSCO", 1, 0, 0, 3, 16, 10, 8,
  "HUANCAVELICA", 0, 0, 0, 0, 0, 6, 14,
  "HUANUCO", 0, 0, 0, 0, 0, 0, 0,
  "ICA", 0, 0, 0, 3, 0, 0, 1,
  "JUNIN", 0, 0, 0, 0, 0, 0, 0,
  "LA LIBERTAD", 0, 0, 0, 0, 0, 0, 1,
  "LAMBAYEQUE", 1, 0, 0, 2, 1, 5, 1,
  "LIMA", 10, 8, 3, 14, 9, 14, 14,
  "LORETO", 1, 1, 2, 0, 3, 3, 2,
  "MADRE DE DIOS", 0, 2, 0, 0, 0, 0, 0,
  "MOQUEGUA", 0, 0, 0, 0, 0, 0, 0,
  "PASCO", 0, 0, 0, 0, 0, 0, 0,
  "PIURA", 1, 2, 0, 0, 1, 0, 0,
  "PUNO", 0, 0, 7, 3, 6, 1, 2,
  "SAN MARTIN", 0, 0, 0, 0, 0, 0, 0,
  "TACNA", 2, 1, 0, 0, 0, 0, 0,
  "TUMBES", 0, 0, 0, 0, 0, 0, 0,
  "UCAYALI", 1, 0, 0, 0, 0, 0, 0
)

# 3. PREPARACIÓN Y MALLA COMPLETA
data_casos <- data_andinos_raw %>%
  pivot_longer(cols = -Departamento, names_to = "Anio", values_to = "Casos")

deptos_mapa <- unique(mapa_sf$NOMBDEP)
anios_data <- unique(data_casos$Anio)

data_final <- expand.grid(NOMBDEP = deptos_mapa, Anio = anios_data) %>%
  left_join(data_casos, by = c("NOMBDEP" = "Departamento", "Anio")) %>%
  mutate(
    # Convertimos 0 a NA para transparencia (truco de doble capa)
    Casos_Plot = if_else(is.na(Casos) | Casos == 0, NA_real_, Casos),
    Texto = paste0("<b>", NOMBDEP, "</b><br>Año: ", Anio, "<br>Casos: ", replace_na(Casos, 0))
  ) %>%
  arrange(Anio)

# 4. MAPA DOBLE CAPA (Fondo Gris + Datos Rojos)
plot_ly() %>%
  
  # CAPA 1: ESQUELETO (Fondo Gris Fijo con bordes blancos)
  add_trace(
    type = "choropleth",
    geojson = geojson_peru,
    locations = mapa_sf$NOMBDEP,
    z = rep(1, nrow(mapa_sf)),
    featureidkey = "properties.NOMBDEP",
    colorscale = list(c(0, 1), c("#eeeeee", "#eeeeee")),
    showscale = FALSE,
    marker = list(line = list(width = 1, color = "white")),
    hoverinfo = "text",
    text = mapa_sf$NOMBDEP,
    inherit = FALSE
  ) %>%
  
  # CAPA 2: DATOS ANIMADOS (Rojos)
  add_trace(
    data = data_final,
    type = "choropleth",
    geojson = geojson_peru,
    locations = ~NOMBDEP,
    featureidkey = "properties.NOMBDEP",
    z = ~Casos_Plot,
    frame = ~Anio,
    colorscale = "Reds",
    zmin = 1,
    zmax = max(data_final$Casos, na.rm = TRUE), # Máximo dinámico según estos datos
    marker = list(line = list(width = 1, color = "white")),
    text = ~Texto,
    hoverinfo = "text"
  ) %>%
  
  layout(
    title = list(text = "", font = list(size = 18)),
    geo = list(
      scope = 'south america',
      showland = FALSE,
      showcountries = FALSE,
      showframe = FALSE,
      showcoastlines = FALSE,
      projection = list(type = 'mercator'),
      center = list(lat = -9.5, lon = -75),
      lataxis = list(range = c(-18.5, 0)),
      lonaxis = list(range = c(-81.5, -68.5)),
      bgcolor = "rgba(0,0,0,0)"
    ),
    margin = list(t = 50, l = 0, r = 0, b = 0)
  ) %>%
  
  animation_opts(
    frame = 1500, 
    transition = 700, 
    redraw = TRUE
  ) %>%
  animation_slider(
    currentvalue = list(prefix = "Año: ")
  ) %>%
  colorbar(title = "N° Casos")
Code
make_download_table(data_andinos_raw, "data_andinos_raw")